#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <errno.h>

#define SOCKET_PATH "/tmp/uds_socket"
#define MESSAGE_SIZE 1024  // 每个消息的大小
#define SEND_COUNT 10000   // 发送大量的消息，确保缓冲区会满

void set_socket_nonblocking(int sock) {
    int flags = fcntl(sock, F_GETFL, 0);
    fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}

void set_socket_sndbuf_size(int sock, int size) {
    if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) == -1) {
        perror("setsockopt SO_SNDBUF");
        exit(EXIT_FAILURE);
    }
}

int main() {
    int sock;
    struct sockaddr_un addr;
    char message[MESSAGE_SIZE];
    ssize_t num_bytes;
    int i;

    // 填充消息数据
    memset(message, 'A', MESSAGE_SIZE);

    // 创建 UNIX 域套接字
    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    memset(&addr, 0, sizeof(struct sockaddr_un));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);

    // 连接服务器
    if (connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
        perror("connect");
        exit(EXIT_FAILURE);
    }

    // 设置为非阻塞模式
    set_socket_nonblocking(sock);

    // 设置发送缓冲区大小为较小的值（模拟缓冲区填满）
    set_socket_sndbuf_size(sock, 1024);  // 设置发送缓冲区为1024字节

    // 模拟发送大量数据，确保缓冲区被填满
    for (i = 0; i < SEND_COUNT; i++) {
        num_bytes = send(sock, message, MESSAGE_SIZE, 0);
        if (num_bytes == -1) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                printf("Buffer is full, cannot send right now. Retrying...\n");
                usleep(100000);  // 等待 100ms 再尝试
            } else {
                perror("send");
                break;
            }
        } else {
            printf("Sent message %d\n", i + 1);
        }
    }

    close(sock);
    return 0;
}
